﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using iTool.SQL.Analysis.Context;
using iTool.SQL.Analysis.Context.Options;

using Microsoft.SqlServer.Management.SqlParser.SqlCodeDom;

namespace iTool.SQL.Analysis.Common
{
    public class SqlStatementErrorOfLimitAnalysis : SqlAnalysisBase
    {
        public SqlStatementErrorOfLimitAnalysis(SqlAnalysisContext context) : base(context)
        {
        }

        public override void Analysis()
        {
            try
            {
                if (base.CodeObject.Sql.StartsWith("limit "))
                {
                    string[] arrays = base.CodeObject.Sql.Split(' ');
                    switch (arrays.Length)
                    {
                        case var t when t == 2 || t == 4:

                            SQLTableOptions? table = null;

                            if (base.context is SqlSelectAnalysisContext select)
                            {
                                table = select.QueryTables.First();
                            }
                            else if (base.context is SqlUpdateAnalysisContext update)
                            {
                                table = update.ChildrenQuerys?[^1].QueryTables[^1];
                            }
                            else if (base.context is SqlInsertAnalysisContext insert)
                            {
                                table = insert.ChildrenQuerys?[^1].QueryTables[^1];
                            }
                            else if (base.context is SqlDeleteAnalysisContext delete)
                            {
                                table = delete.ChildrenQuerys?[^1].QueryTables[^1];
                            }

                            if (table == null)
                            {
                                base.context.Errors.Add("error:" + base.CodeObject.Sql);
                                return;
                            }

                            long.TryParse(arrays[1], out long value);
                            if (value > 0)
                            {
                                table.Limit = value;
                                if (t == 4)
                                {
                                    if (arrays[2] == "offset")
                                    {
                                        long.TryParse(arrays[3], out value);
                                        if (value > 0)
                                        {
                                            table.Offset = value;
                                            return;
                                        }
                                    }
                                }
                                else
                                    return;
                            }

                            base.context.Errors.Add("error:" + base.CodeObject.Sql);
                            break;

                        default:
                            base.context.Errors.Add("error:" + base.CodeObject.Sql);
                            break;
                    }
                }
                else
                {
                    base.context.Errors.Add("error:" + base.CodeObject.Sql);
                }
            }
            catch (Exception ex)
            {
                    base.context.Errors.Add("error:" + base.CodeObject.Sql);
                    base.context.Errors.Add("(SqlStatementErrorOfLimitAnalysis):" + ex.Message);
            }
        }

        public override bool Validation(SqlCodeObject codeObject) => true;
    }
}
